using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GameFramework.Fsm;
using GameFramework.Procedure;
using GameFramework.Localization;
using UnityGameFramework.Runtime;
using System.Data;
using System.Linq;
using System.IO;

namespace LS.Procedure
{
    public class ProcedureAppLaunch : ProcedureBase
    {
        public override bool UseNativeDialog => false;

        protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
        {
            base.OnEnter(procedureOwner);
            // 构建信息：发布版本时，将一些默认数据配置到BuiltinComponent中，运行时供游戏逻辑读取
            var builtin = LSEntry.BuiltinData;
            builtin.InitConfigs();

            //配置语言的支持状态
            InitLanguageSupportSetting();

            // 语言配置：设置当前使用的语言，如果不设置，则默认使用操作系统语言
            InitLanguageSettings();

            // 变体配置：根据使用的语言，通知底层加载对应的资源变体
            InitCurrentVariant();

            // 声音配置：根据用户配置数据，设置即将使用的声音选项
            InitSoundSettings();

            // 此字典文件记录了资源更新前使用的各种语言的字符串，会随 App 一起发布，故不可更新
            builtin.InitDefaultLanguageDictionary();
        }

        protected override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
            ChangeToNextProcedure(procedureOwner);
        }

        protected override void OnLeave(IFsm<IProcedureManager> procedureOwner, bool isShutdown)
        {
            base.OnLeave(procedureOwner, isShutdown);
        }


        private void InitLanguageSupportSetting()
        {
            var languageNames = Enum.GetNames(typeof(Language));
            string localizationDirectory = $"{Application.streamingAssetsPath}/Resources/Localization";
            var config = LSEntry.Config;
            for (int i = 0; i < languageNames.Length; i++)
            {
                bool support = Directory.Exists($"{localizationDirectory}/{languageNames[i]}");
                config.AddConfig($"Language.Supported.{languageNames[i]}", support, default, default, default);
            }
        }


        private void InitLanguageSettings()
        {
            if (LSEntry.Base.EditorResourceMode && LSEntry.Base.EditorLanguage != Language.Unspecified)
            {
                // 编辑器资源模式直接使用 Inspector 上设置的语言
                return;
            }

            string languageDefaultKey = "Language.Default";
            string settingLanguageKey = "Setting.Language";
            string defaultLanguageName = LSEntry.Config.GetString(languageDefaultKey, Language.ChineseSimplified.ToString());

            Language language = LSEntry.Localization.Language;
            Language defaultLanguage = Enum.Parse<Language>(LSEntry.Config.GetString(languageDefaultKey, defaultLanguageName));

            if (LSEntry.Setting.HasSetting(settingLanguageKey))
            {
                string languageString = LSEntry.Setting.GetString(settingLanguageKey, defaultLanguageName);
                language = Enum.Parse<Language>(languageString);
            }
            else
            {
                LSEntry.Setting.SetString(settingLanguageKey, defaultLanguageName);
                language = defaultLanguage;
            }

            if (LSEntry.Config.GetBool($"Language.Supported.{language.ToString()}", false) == false)
            {
                language = defaultLanguage;
            }

            LSEntry.Localization.Language = language;
            LSEntry.Setting.SetString(settingLanguageKey, language.ToString());
            LSEntry.Setting.Save();

            Log.Info("Init language settings complete, current language is '{0}'.", language.ToString());
        }

        private void InitCurrentVariant()
        {
            if (LSEntry.Base.EditorResourceMode)
            {
                // 编辑器资源模式不使用 AssetBundle，也就没有变体了
                return;
            }
            string language = LSEntry.Localization.Language.ToString();
            LSEntry.Resource.SetCurrentVariant(language);
            Log.Info("Init current variant complete.");
        }
        private void InitSoundSettings()
        {
            LSEntry.Sound.Mute("Music", LSEntry.Setting.GetBool("Setting.MusicMuted", false));
            LSEntry.Sound.SetVolume("Music", LSEntry.Setting.GetFloat("Setting.MusicVolume", 1f));
            LSEntry.Sound.Mute("Sound", LSEntry.Setting.GetBool("Setting.SoundMuted", false));
            LSEntry.Sound.SetVolume("Sound", LSEntry.Setting.GetFloat("Setting.SoundVolume", 1f));
            LSEntry.Sound.Mute("UISound", LSEntry.Setting.GetBool("Setting.UISoundMuted", false));
            LSEntry.Sound.SetVolume("UISound", LSEntry.Setting.GetFloat("Setting.UISoundVolume", 1f));
            Log.Info("Init sound settings complete.");
        }

        private void ChangeToNextProcedure(IFsm<IProcedureManager> procedureOwner)
        {
            Type nextProcedureType = ProcedurePreloaderBase.GetFirstProloadProcedure().GetType();
            ChangeState(procedureOwner, nextProcedureType);
        }
    }
}